home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
e33el2.zip
/
emacs
/
19.33
/
lisp
/
skeleton.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-07-02
|
23KB
|
584 lines
;;; skeleton.el --- Lisp language extension for writing statement skeletons
;; Copyright (C) 1993, 1994, 1995, 1996 by Free Software Foundation, Inc.
;; Author: Daniel.Pfeiffer@Informatik.START.dbp.de, fax (+49 69) 7588-2389
;; Maintainer: FSF
;; Keywords: extensions, abbrev, languages, tools
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Commentary:
;; A very concise language extension for writing structured statement
;; skeleton insertion commands for programming language modes. This
;; originated in shell-script mode and was applied to ada-mode's
;; commands which shrunk to one third. And these commands are now
;; user configurable.
;;; Code:
;; page 1: statement skeleton language definition & interpreter
;; page 2: paired insertion
;; page 3: mirror-mode, an example for setting up paired insertion
(defvar skeleton-transformation nil
"*If non-nil, function applied to literal strings before they are inserted.
It should take strings and characters and return them transformed, or nil
which means no transformation.
Typical examples might be `upcase' or `capitalize'.")
; this should be a fourth argument to defvar
(put 'skeleton-transformation 'variable-interactive
"aTransformation function: ")
(defvar skeleton-autowrap t
"Controls wrapping behaviour of functions created with `define-skeleton'.
When the region is visible (due to `transient-mark-mode' or marking a region
with the mouse) and this is non-`nil' and the function was called without an
explicit ARG, then the ARG defaults to -1, i.e. wrapping around the visible
region.
We will probably delete this variable in a future Emacs version
unless we get a substantial number of complaints about the auto-wrap
feature.")
(defvar skeleton-end-hook
(lambda ()
(or (eolp) (newline-and-indent)))
"Hook called at end of skeleton but before going to point of interest.
By default this moves out anything following to next line.
The variables `v1' and `v2' are still set when calling this.")
;;;###autoload
(defvar skeleton-filter 'identity
"Function for transforming a skeleton proxy's aliases' variable value.")
(defvar skeleton-untabify t
"When non-`nil' untabifies when deleting backwards with element -ARG.")
(defvar skeleton-newline-indent-rigidly nil
"When non-`nil', indent rigidly under current line for element `\\n'.
Else use mode's `indent-line-function'.")
(defvar skeleton-further-elements ()
"A buffer-local varlist (see `let') of mode specific skeleton elements.
These variables are bound while interpreting a skeleton. Their value may
in turn be any valid skeleton element if they are themselves to be used as
skeleton elements.")
(make-variable-buffer-local 'skeleton-further-elements)
(defvar skeleton-subprompt
(substitute-command-keys
"RET, \\<minibuffer-local-map>\\[abort-recursive-edit] or \\[help-command]")
"*Replacement for %s in prompts of recursive subskeletons.")
(defvar skeleton-abbrev-cleanup nil
"Variable used to delete the character that led to abbrev expansion.")
(defvar skeleton-debug nil
"*If non-nil `define-skeleton' will override previous definition.")
;; reduce the number of compiler warnings
(defvar skeleton)
(defvar skeleton-modified)
(defvar skeleton-point)
(defvar skeleton-regions)
;;;###autoload
(defmacro define-skeleton (command documentation &rest skeleton)
"Define a user-configurable COMMAND that enters a statement skeleton.
DOCUMENTATION is that of the command, while the variable of the same name,
which contains the skeleton, has a documentation to that effect.
INTERACTOR and ELEMENT ... are as defined under `skeleton-insert'."
(if skeleton-debug
(set command skeleton))
`(progn
(defun ,command (&optional str arg)
,(concat documentation
(if (string-match "\n\\>" documentation)
"" "\n")
"\n"
"This is a skeleton command (see `skeleton-insert').
Normally the skeleton text is inserted at point, with nothing \"inside\".
If there is a highlighted region, the skeleton text is wrapped
around the region text.
A prefix argument ARG says to wrap the skeleton around the next ARG words.
A prefix argument of zero says to wrap around zero words---that is, nothing.
This is a way of overiding the use of a highlighted region.")
(interactive "*P\nP")
(skeleton-proxy-new ',skeleton str arg))))
;;;###autoload
(defun skeleton-proxy-new (skeleton &optional str arg)
"Insert skeleton defined by variable of same name (see `skeleton-insert').
Prefix ARG allows wrapping around words or regions (see `skeleton-insert').
If no ARG was given, but the region is visible, ARG defaults to -1 depending
on `skeleton-autowrap'. An ARG of M-0 will prevent this just for once.
This command can also be an abbrev expansion (3rd and 4th columns in
\\[edit-abbrevs] buffer: \"\" command-name).
When called as a function, optional first argument STR may also be a string
which will be the value of `str' whereas the skeleton's interactor is then
ignored."
(interactive "*P\nP")
(setq skeleton (funcall skeleton-filter skeleton))
(if (not skeleton)
(if (memq this-command '(self-insert-command
skeleton-pair-insert-maybe
expand-abbrev))
(setq buffer-undo-list (primitive-undo 1 buffer-undo-list)))
(skeleton-insert skeleton
(if (setq skeleton-abbrev-cleanup
(or (eq this-command 'self-insert-command)
(eq this-command
'skeleton-pair-insert-maybe)))
()
;; Pretend C-x a e passed its prefix arg to us
(if (or arg current-prefix-arg)
(prefix-numeric-value (or arg
current-prefix-arg))
(and skeleton-autowrap
(or (eq last-command 'mouse-drag-region)
(and transient-mark-mode mark-active))
-1)))
(if (stringp str)
str))
(and skeleton-abbrev-cleanup
(setq skeleton-abbrev-cleanup (point))
(add-hook 'post-command-hook 'skeleton-abbrev-cleanup nil t))))
;; This command isn't meant to be called, only it's aliases with meaningful
;; names are.
;;;###autoload
(defun skeleton-proxy (&optional str arg)
"Insert skeleton defined by variable of same name (see `skeleton-insert').
Prefix ARG allows wrapping around words or regions (see `skeleton-insert').
If no ARG was given, but the region is visible, ARG defaults to -1 depending
on `skeleton-autowrap'. An ARG of M-0 will prevent this just for once.
This command can also be an abbrev expansion (3rd and 4th columns in
\\[edit-abbrevs] buffer: \"\" command-name).
When called as a function, optional first argument STR may also be a string
which will be the value of `str' whereas the skeleton's interactor is then
ignored."
(interactive "*P\nP")
(let ((function (nth 1 (backtrace-frame 1))))
(if (eq function 'nth) ; uncompiled Lisp function
(setq function (nth 1 (backtrace-frame 5)))
(if (eq function 'byte-code) ; tracing byte-compiled function
(setq function (nth 1 (backtrace-frame 2)))))
(if (not (setq function (funcall skeleton-filter (symbol-value function))))
(if (memq this-command '(self-insert-command
skeleton-pair-insert-maybe
expand-abbrev))
(setq buffer-undo-list (primitive-undo 1 buffer-undo-list)))
(skeleton-insert function
(if (setq skeleton-abbrev-cleanup
(or (e